package cn.com.jinhao.provider.user.service.impl;

import cn.com.jinhao.hotline.commons.exception.BusinessErrorException;
import cn.com.jinhao.provider.user.entity.SysMenu;
import cn.com.jinhao.provider.user.entity.SysRoleMenu;
import cn.com.jinhao.provider.user.mapper.CommonMapper;
import cn.com.jinhao.provider.user.mapper.RoleMapper;
import cn.com.jinhao.provider.user.mapper.SysMenuMapper;
import cn.com.jinhao.provider.user.mapper.SysRoleMenuMapper;
import cn.com.jinhao.provider.user.service.MenuService;
import cn.com.jinhao.provider.user.vo.MenuRequestVO;
import cn.com.jinhao.provider.user.vo.MenuSRequestVo;
import cn.com.jinhao.provider.user.vo.MenuURequestVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * HotLine
 * <p>Description: 路由服务实现 </p>
 *
 * @author ShaneMew
 * @version 1.0
 * @date 2020-03-04
 * @since 2020-03-04
 */

@Service
public class MenuServiceImpl implements MenuService {
    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private CommonMapper commonMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(MenuRequestVO menuRequestVO) throws Exception {
        // 如果请求参数里包含父路由都话，检查父路由是否存在
        if (Optional.ofNullable(menuRequestVO.getPid()).isPresent()) {
            Optional.ofNullable(sysMenuMapper.selectByPrimaryKey(menuRequestVO.getPid())).orElseThrow(() -> new BusinessErrorException("父路由ID：" + menuRequestVO.getPid() + "不存在"));
        }

        String code = commonMapper.getCode("SYS_MENU");
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(menuRequestVO, sysMenu);
        code = StringUtils.isBlank(code) ? "0" : String.valueOf(Integer.parseInt(code) + 1);
        sysMenu.setCode(code);
        sysMenuMapper.insertSelective(sysMenu);

        insertRoleMenu(code, menuRequestVO.getRoles());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String id) throws Exception {

        SysMenu sysMenu = Optional.ofNullable(sysMenuMapper.selectByPrimaryKey(id)).orElseThrow(() -> new BusinessErrorException("路由ID为: " + id + "都路由不存在"));
        String code =  sysMenu.getCode();
        // 查询当前路由是否包含下级路由
        Example example = new Example(SysMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("pid", id);
        Optional.ofNullable(sysMenuMapper.selectByExample(example)).orElseThrow(() -> new BusinessErrorException("当前路由包含下级路由不能删除，请先删除下级路由!"));

        sysMenuMapper.delete(sysMenu);

        deleteRoleMenu(code);
    }

    private void deleteRoleMenu(String code) {
        Example exampleRoleMenu = new Example(SysRoleMenu.class);
        Example.Criteria criteriaRoleMenu = exampleRoleMenu.createCriteria();
        criteriaRoleMenu.andEqualTo("menuCode",code);
        sysRoleMenuMapper.deleteByExample(exampleRoleMenu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(MenuURequestVO menuurequestvo) throws Exception{
        // 检查父路由是否存在
        if (Optional.ofNullable(menuurequestvo.getPid()).isPresent()) {
            Optional.ofNullable(sysMenuMapper.selectByPrimaryKey(menuurequestvo.getPid())).orElseThrow(() -> new BusinessErrorException("父路由ID：" + menuurequestvo.getPid() + "不存在"));
        }

        String id = menuurequestvo.getId();
        SysMenu sysMenu = Optional.ofNullable(sysMenuMapper.selectByPrimaryKey(id)).orElseThrow(() -> new BusinessErrorException("路由ID为: " + id + "都路由不存在"));
        String code = sysMenu.getCode();

        BeanUtils.copyProperties(menuurequestvo, sysMenu);
        sysMenuMapper.updateByPrimaryKeySelective(sysMenu);

        // 删除原有都路由角色关系
        deleteRoleMenu(code);

        insertRoleMenu(code, menuurequestvo.getRoles());
    }

    private void insertRoleMenu(String code, List<String> roles) throws Exception {
        List<SysRoleMenu> sysRoleMenuList = new ArrayList<>(10);

        for (String role : roles) {
            // 检查角色是否存在
            Optional.ofNullable(roleMapper.queryByCode(role)).orElseThrow(() -> new BusinessErrorException("当前角色不存在,角色编码为: " + role));
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleCode(role);
            sysRoleMenu.setMenuCode(code);
            sysRoleMenuList.add(sysRoleMenu);
        }
        sysRoleMenuMapper.insertList(sysRoleMenuList);
    }

    @Override
    public List<SysMenu> selectByRoles(MenuSRequestVo sRequestVo) {
        List<SysMenu> sysMenuList = new ArrayList<>(10);
        sRequestVo.getRoles().forEach(role -> {
            List<SysMenu> sysMenus = sysMenuMapper.selectByRole(role);
            if (Optional.ofNullable(sysMenus).isPresent()) {
                sysMenuList.addAll(sysMenus);
            }
        });
        return sysMenuList;
    }
}
